package com.mazaiting.scheduler.domain.bean;

import com.mazaiting.common.core.utils.ThrowableUtil;
import com.mazaiting.web.holder.SpringContextHolder;
import com.mazaiting.scheduler.constant.SchedulerConstant;
import com.mazaiting.scheduler.domain.entity.SysQuartzJob;
import com.mazaiting.scheduler.domain.entity.SysQuartzLog;
import com.mazaiting.scheduler.runner.QuartzRunnable;
import com.mazaiting.scheduler.service.ISysQuartzJobService;
import com.mazaiting.scheduler.service.ISysQuartzLogService;
import com.mazaiting.scheduler.service.impl.SysQuartzJobServiceImpl;
import com.mazaiting.scheduler.service.impl.SysQuartzLogServiceImpl;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.quartz.QuartzJobBean;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.Future;

import static com.mazaiting.scheduler.config.QuartzConfig.SCHEDULED_EXECUTOR_SERVICE;

/**
 * 可执行任务 Bean
 * 参考人人开源，<a href="https://gitee.com/renrenio/renren-security">...</a>
 *
 * @author mazaiting
 * @create_time 2022/4/5 23:39
 */
// 异步执行
@Async
public class ExecutionJobBean extends QuartzJobBean {
    /**
     * 日志工具
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 线程池, 待自定义
     */
    @Resource(name = SCHEDULED_EXECUTOR_SERVICE)
    private AsyncTaskExecutor scheduledExecutor;

    @Override
    public void executeInternal(JobExecutionContext context) {
        // 获取定时任务
        SysQuartzJob quartzJob = (SysQuartzJob) context.getMergedJobDataMap().get(SchedulerConstant.JOB_KEY);
        // 日志处理服务
        ISysQuartzLogService sysQuartzLogService = SpringContextHolder.getBean(SysQuartzLogServiceImpl.class);
        // 定时任务服务
        ISysQuartzJobService sysQuartzJobService = SpringContextHolder.getBean(SysQuartzJobServiceImpl.class);
        // 插入日志
        SysQuartzLog sysQuartzLog = new SysQuartzLog();
        sysQuartzLog.setJobName(quartzJob.getJobName());
        sysQuartzLog.setBeanName(quartzJob.getBeanName());
        sysQuartzLog.setMethodName(quartzJob.getMethodName());
        sysQuartzLog.setParams(quartzJob.getParams());
        sysQuartzLog.setEmail("mazaiting@foxmail.com");
        long startTime = System.currentTimeMillis();
        sysQuartzLog.setCronExpression(quartzJob.getCronExpression());
        sysQuartzLog.setTime(0);
        sysQuartzLog.setSuccess(false);
        // 插入日志
        try {
            // 执行任务
            logger.info("任务准备执行，任务名称：{}", quartzJob.getJobName());
            QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(), quartzJob.getParams());
            // 线程池执行
            Future<Boolean> future = scheduledExecutor.submit(task);
            // 获取任务执行标志
            Boolean flag = future.get();
            // 执行时间
            long times = System.currentTimeMillis() - startTime;
            sysQuartzLog.setTime((int) times);
            // 任务状态
            sysQuartzLog.setSuccess(flag);
            logger.info("任务执行完毕，任务名称：{} 总共耗时：{} 毫秒", quartzJob.getJobName(), times);
            // 判断是否存在子任务
            if (quartzJob.getSubTask() != null) {
                // 分割子任务 ID
                String[] tasks = quartzJob.getSubTask().split("[,，]");
                for (String id : tasks) {
                    // 执行子任务
                    sysQuartzJobService.execution(sysQuartzJobService.getById(Long.parseLong(id)));
                }
            }
        } catch (Exception e) {
            logger.error("任务执行失败，任务名称：{}" + quartzJob.getJobName(), e);
            long times = System.currentTimeMillis() - startTime;
            // 时间时间
            sysQuartzLog.setTime((int) times);
            // 设置异常信息
            sysQuartzLog.setExceptionDetail(ThrowableUtil.getStackTrace(e));
            // 任务如果失败了暂停
            quartzJob.setPause(quartzJob.getPauseAfterFailure());
            // 发送短信
            if (Objects.nonNull(quartzJob.getPhone())) {

            }
            // 发送邮箱
            if (Objects.nonNull(quartzJob.getEmail())) {
//                EmailService emailService = SpringContextHolder.getBean(EmailService.class);
//                // 邮箱报警
//                EmailVo emailVo = taskAlarm(quartzJob, ThrowableUtil.getStackTrace(e));
//                emailService.send(emailVo, emailService.find());
            }
        } finally {
            // 更新
            sysQuartzLogService.saveOrUpdate(sysQuartzLog);
        }
    }

//    private EmailVo taskAlarm(QuartzJob quartzJob, String msg) {
//        EmailVo emailVo = new EmailVo();
//        emailVo.setSubject("定时任务【"+ quartzJob.getJobName() +"】执行失败，请尽快处理！");
//        Map<String, Object> data = new HashMap<>(16);
//        data.put("task", quartzJob);
//        data.put("msg", msg);
//        TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH));
//        Template template = engine.getTemplate("email/taskAlarm.ftl");
//        emailVo.setContent(template.render(data));
//        List<String> emails = Arrays.asList(quartzJob.getEmail().split("[,，]"));
//        emailVo.setTos(emails);
//        return emailVo;
//    }
}

